Option Explicit On
Option Strict On

Imports System.Collections.Generic
Imports TreeCreeper01Interfaces

Public Class cSpatialPlantMapLocationDistances

    Private mInterdistances() As Single


    Public Sub New(ByVal Locations As List(Of ISpatialPlantMapLocation))

        Dim SmallerValueLoopIndex As Integer
        Dim LargerValueLoopIndex As Integer
        Dim LocationOne As ISpatialPlantMapLocation
        Dim LocationTwo As ISpatialPlantMapLocation
        Dim Count As Integer

        Dim MaximumOneDimensionalArraySize As Integer

        Dim DeltaX As Double
        Dim DeltaY As Double
        Dim Interdistance As Single
        Dim OneDimensionalArrayMapping As Integer
        Count = Locations.Count

        MaximumOneDimensionalArraySize = GetOneDimensionalMappingForTwoLocationIndexes(Count - 1, Count)
        ReDim mInterdistances(MaximumOneDimensionalArraySize)

        For SmallerValueLoopIndex = 1 To Count
            LocationOne = Locations.Item(SmallerValueLoopIndex - 1)
            For LargerValueLoopIndex = SmallerValueLoopIndex + 1 To Count
                LocationTwo = Locations.Item(LargerValueLoopIndex - 1)

                DeltaX = LocationOne.xCoordinate - LocationTwo.xCoordinate
                DeltaY = LocationOne.yCoordinate - LocationTwo.yCoordinate
                Interdistance = CType(Math.Sqrt(DeltaX * DeltaX + DeltaY * DeltaY), Single)

                OneDimensionalArrayMapping = GetOneDimensionalMappingForTwoLocationIndexes(SmallerValueLoopIndex, LargerValueLoopIndex)

                If mInterdistances(OneDimensionalArrayMapping) > 0 Then
                    ' should never happen
                    Throw New Exception("OneDimensionalArrayMapping has failed, sorry!")
                End If

                mInterdistances(OneDimensionalArrayMapping) = Interdistance

            Next
        Next

    End Sub


    Public Function GetInterdistanceBetweenTwoLocations(ByVal LocationOne As ISpatialPlantMapLocation, ByVal LocationTwo As ISpatialPlantMapLocation) As Double

        Dim SmallerLocationIndex As Integer
        Dim LargerLocationIndex As Integer
        Dim TempValue As Integer

        Dim OneDimensionalArrayMapping As Integer

        SmallerLocationIndex = LocationOne.Index
        LargerLocationIndex = LocationTwo.Index

        If SmallerLocationIndex > LargerLocationIndex Then
            TempValue = SmallerLocationIndex
            SmallerLocationIndex = LargerLocationIndex
            LargerLocationIndex = TempValue
        End If

        OneDimensionalArrayMapping = GetOneDimensionalMappingForTwoLocationIndexes(SmallerLocationIndex, LargerLocationIndex)

        Return mInterdistances(OneDimensionalArrayMapping)

    End Function

    Private Function GetOneDimensionalMappingForTwoLocationIndexes(ByVal IndexBaseOneWithSmallerValue As Integer, ByVal IndexBaseOneWithLargerValue As Integer) As Integer

        Dim MappingValue As Integer

        ' proper non-overlapping formula for mapping is
        ' floor(((L-1)^2)/2) + S
        MappingValue = CType(Math.Floor((IndexBaseOneWithLargerValue - 1) * (IndexBaseOneWithLargerValue - 1) / 2), Integer) + IndexBaseOneWithSmallerValue

        Return MappingValue

    End Function


End Class